package com.xncoding.kelan;


import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class BankService {
    public static void main(String[] args) throws IOException {
//        createUser("张三","qwq","123456",12);
        CreateUserAPI t1 = new CreateUserAPI();
        t1.setAge(19);
        t1.setName("账款");
        t1.setIdentity("qweq");
        t1.setMobile("1234567890");
//        t1.setIdid("q12q");
//        String call = remoteCall(t1);
//        remoteBack(new CreateUserAPI(),call);

        String str = "    990102    pftran   M0025                              userid=M0025|brchno=990009|servtp=EPC|chanel=epcc|itssdt=20190711|fmprsq=20190711220001878241|itssmb=|itsssq=512b2adfbd7c4b558ea469ad5b197eac|prcscd=pftran|subprc=pftran|trantp=1|acctno=6213392100516661086|odtrsq=123441210|bachsq=B202201180018|tranam=120.00|odtrdt=20211201|paysna=网联|toacct=6222023002021042240|remktx=12|dscrtx=拿去花|toacna=董志敏|";

        System.out.println(str);
        remoteEPCCBack(new epcc(),str);
    }

    //创建用户方法
    public static void createUser(String name, String identity, String mobile, int age) {
        StringBuilder stringBuilder = new StringBuilder();
        //字符串靠左，多余的地方填充_
        stringBuilder.append(String.format("%-10s", name).replace(' ', '_'));
        //数字靠右，多余的地方用0填充
        stringBuilder.append(String.format("%05d", age));
//        stringBuilder.append(String.format("%020d", "mobile"));
        System.out.println(stringBuilder.toString());
    }

    private static String remoteCall(AbstractAPI api) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        Arrays.stream(api.getClass().getDeclaredFields()) //获得所有字段
                .filter(field -> field.isAnnotationPresent(BankAPIField.class)) //查找标记了注解的字段
                .sorted(Comparator.comparingInt(a -> a.getAnnotation(BankAPIField.class).order())) //根据注解中的order对字段排序
                .peek(field -> field.setAccessible(true)) //设置可以访问私有字段
                .forEach(field -> {
                    //获得注解
                    BankAPIField bankAPIField = field.getAnnotation(BankAPIField.class);
                    Object value = "";
                    try {
                        //反射获取字段值
                        value = field.get(api);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    //根据字段类型以正确的填充方式格式化字符串
                    switch (bankAPIField.type()) {
                        case "S": {
                            stringBuilder.append(String.format("%-" + bankAPIField.length() + "s", value.toString()).replace(' ', '_'));
                            break;
                        }
                        case "N": {
                            stringBuilder.append(String.format("%" + bankAPIField.length() + "s", value.toString()).replace(' ', '0'));
                            break;
                        }
                        case "M": {
                            stringBuilder.append(String.format("%0" + bankAPIField.length() + "d", ((BigDecimal) value).setScale(2, RoundingMode.DOWN).multiply(new BigDecimal("100")).longValue()));
                            break;
                        }
                        default:
                            break;
                    }
                });
        //签名逻辑
//        stringBuilder.append(DigestUtils.md2Hex(stringBuilder.toString()));
        String param = stringBuilder.toString();
        System.out.println(param);
        return param;
    }


    private static String remoteBack(AbstractAPI api,String res) throws IOException {
        LinkedHashMap map = new LinkedHashMap();
        AtomicInteger startLen = new AtomicInteger();
        AtomicInteger endLen = new AtomicInteger();
        Arrays.stream(api.getClass().getDeclaredFields()) //获得所有字段
                .filter(field -> field.isAnnotationPresent(BankAPIField.class)) //查找标记了注解的字段
                .sorted(Comparator.comparingInt(a -> a.getAnnotation(BankAPIField.class).order())) //根据注解中的order对字段排序
                .peek(field -> field.setAccessible(true)) //设置可以访问私有字段
                .forEach(field -> {
                    //获得注解
                    BankAPIField bankAPIField = field.getAnnotation(BankAPIField.class);
                    Object keyName = field.getName();
                    endLen.getAndAdd(bankAPIField.length());
                    //根据字段类型以正确的填充方式格式化字符串
                    switch (bankAPIField.type()) {
                        case "S": {
                            map.put(keyName,res.substring(startLen.intValue(),endLen.intValue()));
                            break;
                        }
                        case "N": {
                            map.put(keyName,res.substring(startLen.intValue(),endLen.intValue()));
                            break;
                        }
                        case "M": {
                            map.put(keyName,res.substring(startLen.intValue(),endLen.intValue()));
                            break;
                        }
                        default:
                            break;
                    }
                    startLen.getAndAdd(bankAPIField.length());
                });
        //签名逻辑
//        stringBuilder.append(DigestUtils.md2Hex(stringBuilder.toString()));
        String param = JSON.toJSONString(map);
        System.out.println(param);
        return param;
    }

    private static String remoteEPCCBack(AbstractAPI api,String res) throws IOException {
        LinkedHashMap map = new LinkedHashMap();
        AtomicInteger startLen = new AtomicInteger();
        AtomicInteger endLen = new AtomicInteger();
        Arrays.stream(api.getClass().getDeclaredFields()) //获得所有字段
                .filter(field -> field.isAnnotationPresent(BankAPIField.class)) //查找标记了注解的字段
                .sorted(Comparator.comparingInt(a -> a.getAnnotation(BankAPIField.class).order())) //根据注解中的order对字段排序
                .peek(field -> field.setAccessible(true)) //设置可以访问私有字段
                .forEach(field -> {
                    //获得注解
                    BankAPIField bankAPIField = field.getAnnotation(BankAPIField.class);
                    Object keyName = field.getName();
                    endLen.getAndAdd(bankAPIField.length());
                    //根据字段类型以正确的填充方式格式化字符串
                    switch (bankAPIField.type()) {
                        case "S": {
                            String val = res.substring(startLen.intValue(),endLen.intValue()).trim();
                            if(StringUtils.isEmpty(val)){
                                map.put(keyName,bankAPIField.defaultValue());
                            }else {
                                map.put(keyName,val);
                            }

                            break;
                        }
                        case "END": {
//                            map.put(keyNme,res.substring(startLen.intValue(),res.length()));
                            String val = res.substring(startLen.intValue(),res.length());

                            Map dataMap = splitToMap(val, "|");
                            map.putAll(dataMap);
                            break;
                        }
                        default:
                            break;
                    }
                    startLen.getAndAdd(bankAPIField.length());
                });
        //签名逻辑
//        stringBuilder.append(DigestUtils.md2Hex(stringBuilder.toString()));
        String param = JSON.toJSONString(map);
        System.out.println(param);
        return param;
    }


    public static Map splitToMap(String content, String delim) {
        Map map = new HashMap();
        StringTokenizer st = new StringTokenizer(content, delim);

        if (null != st) {
            String token = null;
            int pos = -1;
            while (st.hasMoreTokens()) {
                token = st.nextToken();
                pos = token.indexOf('=');

                if (-1 != pos && pos != token.length() - 1) {
                    map.put(token.substring(0, pos).trim(), token.substring(pos + 1).trim());
                }
            }
        }

        return map;
    }



}
